import importlib
from . import db

__all__ = ['caches', 'cache', 'BaseCache', "DBCache", "RedisCache"]


class BaseCache(object):
    def __init__(self, location, *args, **kwargs):
        self.location = location

    def set(self, key, value, timeout):
        raise NotImplementedError

    def get(self, key):
        raise NotImplementedError

    def delete(self, key):
        raise NotImplementedError

    def cache(self, key, timeout):
        def func(method):
            def wrapper(*args, **kwarges):
                data = method(*args, **kwarges)
                self.set(key, str(data), timeout)
                return data
            return wrapper

        return func


class DBCache(BaseCache):
    def __init__(self, location, *args, **kwargs):
        super(DBCache, self).__init__(location)

    def get(self, key):
        def get_cache_value(cursor, args):
            info = cursor.fetchone()
            if info is None:
                return None

            return info['value']

        return db.execute("select value from %s where key='%s'" % (self.location, key), get_cache_value)

    def set(self, key, value, timeout):
        value = self.get(key)
        if value is None:
            db.execute("insert into %s value ('%s', '%s', %d" % (self.location, key, value, timeout))
        else:
            db.execute("update %s set value='%s', expire=%d where key='%s'" % (self.location, value, timeout, key))

    def delete(self, key):
        db.execute("delete from %s where key='%s'" % (self.location, key))


class RedisCache(BaseCache):
    def __init__(self, location, *args, **options):
        super(RedisCache, self).__init__(location)
        import redis
        self.redis = redis.Redis(location)

    def set(self, key, value, timeout):
        self.redis.setex(key, value, timeout)

    def get(self, key):
        return self.redis.get(key)

    def delete(self, key):
        return self.redis.delete(key)


class CacheManager():
    def __init__(self, conf):
        # 读取配置并加载每一个Cache对象，并放在caches字典里。
        self._caches = dict()
        for key in conf:
            cache_conf = conf[key]
            module_name, cls = cache_conf['engine'].rsplit(".", 1)
            module = importlib.import_module(module_name)
            Cache = getattr(module, cls)
            assert issubclass(Cache, BaseCache)
            cache = Cache(cache_conf['location'])
            self._caches[key] = cache

    def __getitem__(self, item):
        return self._caches[item]


from . import config

caches = CacheManager(config.caches)
cache = caches["default"]
